package org.jeecg.modules.charge.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.StringUtils;
import org.jeecg.entity.charge.ChargeBills;
import org.jeecg.vo.charge.ComMonthReportReq;
import org.jeecg.vo.charge.ComMonthReportResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.jeecg.modules.charge.mapper.ChargeComMonthReportMapper;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;


@Component
@Transactional(readOnly = true)
@Slf4j
public class ChargeComMonthReportServiceImpl{

	@Autowired
	private ChargeComMonthReportMapper  chargeComMonthReportMapper;

	public List<ComMonthReportResp> getSumCollect(ComMonthReportReq comMonthReport) {
		List<ComMonthReportResp> shouldMonth = chargeComMonthReportMapper.getShouldMonth(comMonthReport);//当月应收
		List<ComMonthReportResp> shouldYear = chargeComMonthReportMapper.selectShouldYear(comMonthReport); //整年应收
		List<ComMonthReportResp> sumShouldYear = chargeComMonthReportMapper.getsumShouldYear(comMonthReport);
		List<ComMonthReportResp> sumOwnYear = chargeComMonthReportMapper.getsumOwnYear(comMonthReport);//旧欠应收
		List<ComMonthReportResp> realMonth = chargeComMonthReportMapper.getRealMonth(comMonthReport);
		List<ComMonthReportResp> realYear = chargeComMonthReportMapper.getRealYear(comMonthReport);
		List<ComMonthReportResp> ownReal = chargeComMonthReportMapper.getownReal(comMonthReport);
		List<ComMonthReportResp> advanceMonth = chargeComMonthReportMapper.getadvanceMonth(comMonthReport);
		List<ComMonthReportResp> advanceMonthTo = chargeComMonthReportMapper.getadvanceMonthTo(comMonthReport);
		List<ComMonthReportResp> advanceBlance = chargeComMonthReportMapper.getAdvanceBlance(comMonthReport);
		List<ComMonthReportResp> sumrealYear = chargeComMonthReportMapper.getsumrealYear(comMonthReport);
		List<ComMonthReportResp> sumRealOwnYear = chargeComMonthReportMapper.getsumRealOwnYear(comMonthReport);
		List<ComMonthReportResp> sumAllMoney = chargeComMonthReportMapper.getsumAllMoney(comMonthReport);
		/*if (null != comMonthReport.getProjectIds() && comMonthReport.getProjectIds().size() > 0 && comMonthReport.getTypes().equals("1")) {
			try {
				mergeListByFid(shouldYear, shouldMonth, "shouldMonth");
				mergeListByFid(shouldYear, sumShouldYear, "sumShouldYear");
				mergeListByFid(shouldYear, sumOwnYear, "sumOwnYear");
				mergeListByFid(shouldYear, realMonth, "realMonth");
				mergeListByFid(shouldYear, realYear, "realYear");
				mergeListByFid(shouldYear, ownReal, "ownReal");
				mergeListByFid(shouldYear, advanceMonth, "advanceMonth");
				mergeListByFid(shouldYear, advanceMonthTo, "advanceMonthTo");
				mergeListByFid(shouldYear, advanceBlance, "advanceBlance");
				mergeListByFid(shouldYear, sumrealYear, "sumrealYear");
				mergeListByFid(shouldYear, sumRealOwnYear, "sumRealOwnYear");
				mergeListByFid(shouldYear, sumAllMoney, "sumAllMoney");
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		}
		if (null != comMonthReport.getFloorIds() && comMonthReport.getFloorIds().size() > 0 && comMonthReport.getTypes().equals("2")) {
			// 拼接List，以fid为标准
			try {
				mergeListByRid(shouldYear, shouldMonth, "shouldMonth");
				mergeListByRid(shouldYear, sumShouldYear, "sumShouldYear");
				mergeListByRid(shouldYear, sumOwnYear, "sumOwnYear");
				mergeListByRid(shouldYear, realMonth, "realMonth");
				mergeListByRid(shouldYear, realYear, "realYear");
				mergeListByRid(shouldYear, ownReal, "ownReal");
				mergeListByRid(shouldYear, advanceMonth, "advanceMonth");
				mergeListByRid(shouldYear, advanceMonthTo, "advanceMonthTo");
				mergeListByRid(shouldYear, advanceBlance, "advanceBlance");
				mergeListByRid(shouldYear, sumrealYear, "sumrealYear");
				mergeListByRid(shouldYear, sumRealOwnYear, "sumRealOwnYear");
				mergeListByRid(shouldYear, sumAllMoney, "sumAllMoney");
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		}

		if (null != comMonthReport.getFloorIds() && comMonthReport.getFloorIds().size() > 0 && comMonthReport.getTypes().equals("3")) {
			// 拼接List，以rid为标准
			try {
				mergeListByRids(shouldYear, shouldMonth, "shouldMonth");
				mergeListByRids(shouldYear, sumShouldYear, "sumShouldYear");
				mergeListByRids(shouldYear, sumOwnYear, "sumOwnYear");
				mergeListByRids(shouldYear, realMonth, "realMonth");
				mergeListByRids(shouldYear, realYear, "realYear");
				mergeListByRids(shouldYear, ownReal, "ownReal");
				mergeListByRids(shouldYear, advanceMonth, "advanceMonth");
				mergeListByRids(shouldYear, advanceMonthTo, "advanceMonthTo");
				mergeListByRids(shouldYear, advanceBlance, "advanceBlance");
				mergeListByRids(shouldYear, sumrealYear, "sumrealYear");
				mergeListByRids(shouldYear, sumRealOwnYear, "sumRealOwnYear");
				mergeListByRids(shouldYear, sumAllMoney, "sumAllMoney");
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		}*/


		/*if (null != commonthReport.getOfids() && commonthReport.getOfids().size() > 0) {
			// 拼接List，以ofid为标准
			try {
				mergeListByOfid(shouldYear, shouldMonth, "shouldMonth");
				mergeListByOfid(shouldYear, sumShouldYear, "sumShouldYear");
				mergeListByOfid(shouldYear, sumOwnYear, "sumOwnYear");
				mergeListByOfid(shouldYear, realMonth, "realMonth");
				mergeListByOfid(shouldYear, realYear, "realYear");
				mergeListByOfid(shouldYear, ownReal, "ownReal");
				mergeListByOfid(shouldYear, advanceMonth, "advanceMonth");
				mergeListByOfid(shouldYear, advanceMonthTo, "advanceMonthTo");
				mergeListByOfid(shouldYear, advanceBlance, "advanceBlance");
				mergeListByOfid(shouldYear, sumrealYear, "sumrealYear");
				mergeListByOfid(shouldYear, sumRealOwnYear, "sumRealOwnYear");
				mergeListByOfid(shouldYear, sumAllMoney, "sumAllMoney");
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		}*/
		try {
			setFieldDefault(shouldYear);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}

		return shouldYear;
	}

	public List<ComMonthReportResp> getSumCollectList(ComMonthReportReq comMonthReport) {
		//基础模板
		List<ComMonthReportResp> baseReportList = chargeComMonthReportMapper.getBaseResp(comMonthReport);
		if (baseReportList == null || baseReportList.size() <= 0) return baseReportList;
		setFieldDefault(baseReportList);
		Map<String,ComMonthReportResp> baseMap = baseReportList.stream().collect(Collectors.toMap(ComMonthReportResp::getBaseKey, Function.identity()));
		List<ComMonthReportResp> shouldMonth = chargeComMonthReportMapper.getShouldMonth(comMonthReport);//当月应收
		List<ComMonthReportResp> shouldYear = chargeComMonthReportMapper.selectShouldYear(comMonthReport); //整年应收
		List<ComMonthReportResp> sumShouldYear = chargeComMonthReportMapper.getsumShouldYear(comMonthReport);
		List<ComMonthReportResp> sumOwnYear = chargeComMonthReportMapper.getsumOwnYear(comMonthReport);//旧欠应收
		List<ComMonthReportResp> realMonth = chargeComMonthReportMapper.getRealMonth(comMonthReport);
		List<ComMonthReportResp> realYear = chargeComMonthReportMapper.getRealYear(comMonthReport);
		List<ComMonthReportResp> ownReal = chargeComMonthReportMapper.getownReal(comMonthReport);
		List<ComMonthReportResp> advanceMonth = chargeComMonthReportMapper.getadvanceMonth(comMonthReport);
		List<ComMonthReportResp> advanceMonthTo = chargeComMonthReportMapper.getadvanceMonthTo(comMonthReport);
		List<ComMonthReportResp> advanceBlance = chargeComMonthReportMapper.getAdvanceBlance(comMonthReport);
		List<ComMonthReportResp> sumrealYear = chargeComMonthReportMapper.getsumrealYear(comMonthReport);
		List<ComMonthReportResp> sumRealOwnYear = chargeComMonthReportMapper.getsumRealOwnYear(comMonthReport);
		List<ComMonthReportResp> sumAllMoney = chargeComMonthReportMapper.getsumAllMoney(comMonthReport);
		wrapReport(baseMap, shouldMonth, "shouldMonth");
		wrapReport(baseMap, shouldYear, "shouldYear");
		wrapReport(baseMap, sumShouldYear, "sumShouldYear");
		wrapReport(baseMap, sumOwnYear, "sumOwnYear");
		wrapReport(baseMap, realMonth, "realMonth");
		wrapReport(baseMap, realYear, "realYear");
		wrapReport(baseMap, ownReal, "ownReal");
		wrapReport(baseMap, advanceMonth, "advanceMonth");
		wrapReport(baseMap, advanceMonthTo, "advanceMonthTo");
		wrapReport(baseMap, advanceBlance, "advanceBlance");
		wrapReport(baseMap, sumrealYear, "sumrealYear");
		wrapReport(baseMap, sumRealOwnYear, "sumRealOwnYear");
		wrapReport(baseMap, sumAllMoney, "sumAllMoney");
		return baseMap.values().stream().collect(Collectors.toList());
	}

	private void wrapReport(Map<String, ComMonthReportResp> baseMap, List<ComMonthReportResp> wrapList, String fieldName)  {
		try {
			if (wrapList.size() == 0) return;
			Field field = ComMonthReportResp.class.getDeclaredField(fieldName);
			field.setAccessible(true);
			for (ComMonthReportResp reportResp:wrapList){
				ComMonthReportResp baseReport = baseMap.get(reportResp.getBaseKey());
				if (baseReport != null){
					field.set(baseReport, field.get(reportResp));
				}
			}
		}catch (Exception e){
			log.error("包装报表异常",e);
		}
	}


	// 根据pid为基准多个list拼接为一个list
	public void mergeListByFid(List<ComMonthReportResp> baseList, List<ComMonthReportResp> diffList, String fieldName)
			throws Exception {
		if (null == diffList || diffList.size() == 0) {
			return;
		}
		Field field = ComMonthReportResp.class.getDeclaredField(fieldName);
		field.setAccessible(true);
		for (ComMonthReportResp item : baseList) {
			String pid = item.getProjectId();
			for (ComMonthReportResp diff : diffList) {
				if (StringUtils.isNotEmpty(diff.getProjectId()) && diff.getProjectId().equals(pid)) {
					field.set(item, field.get(diff));
					break;
				}
			}
		}
	}

	// 根据fid为基准多个list拼接为一个list
	public void mergeListByRid(List<ComMonthReportResp> baseList, List<ComMonthReportResp> diffList, String fieldName)
			throws Exception {
		if (null == diffList || diffList.size() == 0) {
			return;
		}
		Field field = ComMonthReportResp.class.getDeclaredField(fieldName);
		field.setAccessible(true);
		for (ComMonthReportResp item : baseList) {
			String rid = item.getFloorId();
			for (ComMonthReportResp diff : diffList) {
				if (StringUtils.isNotEmpty(diff.getFloorId()) && diff.getFloorId().equals(rid)) {
					field.set(item, field.get(diff));
					break;
				}
			}
		}
	}

	// 根据rid为基准多个list拼接为一个list
	public void mergeListByRids(List<ComMonthReportResp> baseList, List<ComMonthReportResp> diffList, String fieldName)
			throws Exception {
		if (null == diffList || diffList.size() == 0) {
			return;
		}
		Field field = ComMonthReportResp.class.getDeclaredField(fieldName);
		field.setAccessible(true);
		for (ComMonthReportResp item : baseList) {
			String rid = item.getRoomId();
			for (ComMonthReportResp diff : diffList) {
				try{
					if (StringUtils.isNotEmpty(diff.getRoomId()) && diff.getRoomId().equals(rid)) {
						field.set(item, field.get(diff));
						break;
					}
				}catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

//	// 根据ofid为基准多个list拼接为一个list
//	public void mergeListByOfid(List<ComMonthReportResp> baseList, List<ComMonthReportResp> diffList, String fieldName)
//			throws Exception {
//		if (null == diffList || diffList.size() == 0) {
//			return;
//		}
//		Field field = ComMonthReportResp.class.getDeclaredField(fieldName);
//		field.setAccessible(true);
//		for (ComMonthReportResp item : baseList) {
//			String address = item.getAddress();
//			for (ComMonthReportResp diff : diffList) {
//				if (StringUtils.isNotEmpty(diff.getAddress()) && diff.getAddress().equals(address)) {
//					field.set(item, field.get(diff));
//					break;
//				}
//			}
//		}
//	}

	// 获取对象的属性值NULL设置为0.0
	public void setFieldDefault(List<ComMonthReportResp> wyChargerfees){
		try {
			// 循环判断属性，为NULL的直接为0.0
			for (ComMonthReportResp wy : wyChargerfees) {
				// 获取实体类的所有属性，返回Field数组
				Field[] field = wy.getClass().getDeclaredFields();
				// 循环遍历获得属性值
				for (int j = 0; j < field.length; j++) {
					// 属性为private的需要设置true
					field[j].setAccessible(true);
					// 获取属性名
					String oldname = field[j].getName();
					// 将属性的首字符大写，方便构造get，set方法
					String name = oldname.substring(0, 1).toUpperCase() + oldname.substring(1);
					// 获取属性的类型
					String type = field[j].getGenericType().toString();
					// 判断属性类型是Double
					if (type.equals("class java.lang.Double")) {
						Method m = wy.getClass().getMethod("get" + name);
						Double value = (Double) m.invoke(wy);
						// 如果当前属性值为null时则set为0.0
						if (null == value) {
							// 根据属性名获取
							Field f = wy.getClass().getDeclaredField(oldname);
							f.setAccessible(true);
							f.set(wy, 0.0);
						}
					}
				}
			}
		}catch (Exception e){
			log.error(e.getMessage(),e);
		}
	}
	//综合月报表详情
	public List<ChargeBills> detailList(ComMonthReportReq commonthReport, Page<ChargeBills> page) {
		List<ChargeBills> list = null;
		if(commonthReport.getBillsTypes().equals("shouldMonth")){
			 list = chargeComMonthReportMapper.shouldMonthDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("sumShouldYear")){ //当年累计应收详情
			list = chargeComMonthReportMapper.sumShouldYearDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("getsumOwnYear")){ //旧欠应收
			 list = chargeComMonthReportMapper.sumOwnYearDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("shouldOwnYear")){//合计应收  (旧欠应收 + 当年累计应收)
			list = chargeComMonthReportMapper.sumDueYearDetails(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("realMonthDetailed")){//收当月详情
			list = chargeComMonthReportMapper.realMonthDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("realYearDetailed")){//收当年详情
			list = chargeComMonthReportMapper.realYearDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("ownRealDetailed")){ // 收旧欠详情
			list = chargeComMonthReportMapper.ownRealDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("advanceMonthDetailed")){ // 预收详情
			list = chargeComMonthReportMapper.advanceMonthDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("realownad")){//实收合计 (收当月详情 + 收当年详情 + 收旧欠详情 + 预收详情)
			list = chargeComMonthReportMapper.sumRealYearDetails(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("advanceMonthToDetailed")){
			list = chargeComMonthReportMapper.advanceMonthToDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("advanceBlanceDetailed")){
			list = chargeComMonthReportMapper.advanceBlanceDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("sumrealYearDetailed")){
			list = chargeComMonthReportMapper.sumrealYearDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("sumRealOwnYearDetailed")){
			list = chargeComMonthReportMapper.sumRealOwnYearDetailed(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("sumRealOwnReal")){//收欠费详情 ( 收当年详情 + 收旧欠详情)
			list = chargeComMonthReportMapper.sumRealOverdueYearDetails(commonthReport,page);
		}
		if(commonthReport.getBillsTypes().equals("sumAllMoneyDetailed")){//账面累计实收详情
			list = chargeComMonthReportMapper.sumAllMoneyDetailed(commonthReport,page);
		}
		return list;
	}

	/**
	   * @param excelName
	   * double计算保留两位小数
	   * @return
	   * @throws IOException
	   */
	private Double getBigDecimal(Double sum){
		BigDecimal bigsum = new BigDecimal(sum);
		Double sums = bigsum.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		return sums;
	}
}
